home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / zmisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-07  |  21.8 KB  |  715 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello  */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                 Zmodem routines used by Zsend and Zreceive               */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*    For complete  details  of the licensing restrictions, please refer    */
  17. /*    to the License  agreement,  which  is published in its entirety in    */
  18. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  19. /*                                                                          */
  20. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  21. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  22. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  23. /*    NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  24. /*    AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  25. /*    USE   THIS  FILE  WITHOUT  HAVING   ACCEPTED  THE  TERMS  OF   THE    */
  26. /*    BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER  AGREEMENT AS YOU    */
  27. /*    ARE ABLE TO REACH WITH THE AUTHORS.                                   */
  28. /*                                                                          */
  29. /*                                                                          */
  30. /*    The Authors can be reached at the following addresses:                */
  31. /*                                                                          */
  32. /*    Robert C. Hartman                      Vincent E. Perriello           */
  33. /*    Spark Software                         VEP Software                   */
  34. /*    427-3 Amherst Street                   111 Carroll Street             */
  35. /*    CS2032, Suite 232                      Naugatuck, CT 06770            */
  36. /*    Nashua, NH 03061                                                      */
  37. /*                                                                          */
  38. /*    FidoNet 1:132/101                      FidoNet 1:141/491              */
  39. /*    Data    (603) 888-8179                 Data    (203) 729-7569         */
  40. /*                                                                          */
  41. /*    Please feel free to contact us at any time to share your comments     */
  42. /*    about our software and/or licensing policies.                         */
  43. /*                                                                          */
  44. /*                                                                          */
  45. /*  This module is based largely on a similar module in OPUS-CBCS V1.03b.   */
  46. /*  The original work is (C) Copyright 1986, Wynn Wagner III. The original  */
  47. /*  authors have graciously allowed us to use their code in this work.      */
  48. /*                                                                          */
  49. /*--------------------------------------------------------------------------*/
  50.  
  51.  
  52. #include <conio.h>
  53.  
  54. #ifdef __TURBOC__
  55. #include <alloc.h>
  56. #else
  57. #include <malloc.h>
  58. #endif
  59.  
  60. #include "com.h"
  61. #include "xfer.h"
  62. #include "zmodem.h"
  63. #include "keybd.h"
  64. #include "sbuf.h"
  65. #include "sched.h"
  66. #include "externs.h"
  67. #include "prototyp.h"
  68.  
  69.  
  70. static int Rxtype;                               /* Type of header received                 */
  71.  
  72. static char hex[] = "0123456789abcdef";
  73.  
  74. /* Send a byte as two hex digits */
  75. #define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
  76.  
  77. /*--------------------------------------------------------------------------*/
  78. /* Private routines                                                         */
  79. /*--------------------------------------------------------------------------*/
  80. static int _Z_qk_read (void);
  81. static int _Z_GetBinaryHeader (unsigned char *);
  82. static int _Z_32GetBinaryHeader (unsigned char *);
  83. static int _Z_GetHexHeader (unsigned char *);
  84. static int _Z_GetHex (void);
  85. static int _Z_TimedRead (void);
  86. static long _Z_PullLongFromHeader (unsigned char *);
  87.  
  88. void z_message (s)
  89. byte *s;
  90. {
  91.    if (fullscreen && un_attended)
  92.       {
  93.       if (s)
  94.          {
  95.          sb_move (filewin, 2, 27);
  96.          sb_puts (filewin, s);
  97.          }
  98.       sb_puts (filewin, "              ");
  99.       sb_show ();
  100.       }
  101.    else
  102.       {
  103.       gotoxy (locate_x + 20, locate_y);
  104.       if (s)
  105.          {
  106.          cputs (s);
  107.          }
  108.       cputs ("               ");
  109.       }
  110. }
  111.  
  112. void z_log (s)
  113. char *s;
  114. {
  115.    word x, y;
  116.  
  117.    z_message (s);
  118.  
  119.    x = locate_x;
  120.    y = locate_y;
  121.    status_line (s);                              /* also does disk file
  122.                                                   * logging */
  123.    locate_x = x;
  124.    locate_y = y;
  125. }
  126.  
  127. void show_loc (l, w)
  128. unsigned long l;
  129. unsigned int w;
  130. {
  131.    char j[100];
  132.  
  133.    if (fullscreen && un_attended)
  134.       {
  135.       sb_move (filewin, 2, 37);
  136.       sprintf (j, "Ofs=%ld Retries=%d        ", l, w);
  137.       sb_puts (filewin, j);
  138.       sb_show ();
  139.       }
  140.    else
  141.       {
  142.       gotoxy (locate_x + 35, locate_y);
  143.       cprintf ("Ofs=%ld Retries=%d        ", l, w);
  144.       }
  145. }
  146.  
  147. char *zalloc ()
  148. {
  149.    byte *sptr;
  150.  
  151.    sptr = malloc (WAZOOMAX + 16);
  152.    if (!sptr)
  153.       {
  154.       status_line ("!Z-MEMOVFL");
  155.       adios (2);
  156.       }
  157.    return sptr;
  158. }
  159.  
  160. /*--------------------------------------------------------------------------*/
  161. /* Z GET BYTE                                                               */
  162. /* Get a byte from the modem;                                               */
  163. /* return TIMEOUT if no read within timeout tenths,                         */
  164. /* return RCDO if carrier lost                                              */
  165. /*--------------------------------------------------------------------------*/
  166. /*PLF Sat  05-06-1989  05:47:32; heavy clean up job. */
  167. int Z_GetByte (tenths)
  168. int tenths;
  169. {
  170.     long timeout;
  171.  
  172.     if(CHAR_AVAIL())
  173.         return MODEM_IN();
  174.  
  175.     timeout = timerset(tenths * 10);
  176.  
  177.     do{
  178.         if(CHAR_AVAIL())
  179.             return MODEM_IN();
  180.         if(!CARRIER)
  181.             return RCDO;
  182.         if(got_ESC()) return -1;
  183.         time_release();
  184.     }
  185.     while(!timeup(timeout));
  186.  
  187.     return TIMEOUT;
  188. }
  189.  
  190. /*--------------------------------------------------------------------------*/
  191. /* QK_READ  (like Z_GetByte, but assumes the time to be Rxtimeout)          */
  192. /* Get a byte from the modem;                                               */
  193. /* return TIMEOUT if no read within timeout tenths,                         */
  194. /* return RCDO if carrier lost                                              */
  195. /*--------------------------------------------------------------------------*/
  196. /*PLF Sat  05-06-1989  05:51:11; Turned it into a macro. */
  197. #define _Z_qk_read()  Z_GetByte(Rxtimeout)
  198.  
  199. /*--------------------------------------------------------------------------*/
  200. /* Z PUT STRING                                                             */
  201. /* Send a string to the modem, processing for \336 (sleep 1 sec)            */
  202. /* and \335 (break signal, ignored)                                         */
  203. /*--------------------------------------------------------------------------*/
  204. void Z_PutString (s)
  205. register unsigned char *s;
  206. {
  207.    register int c;
  208.  
  209.    while (*s)
  210.       {
  211.       switch (c = *s++)
  212.          {
  213.          case '\336':
  214.             big_pause (2);
  215.          case '\335':
  216. /* Should send a break on this */
  217.             break;
  218.          default:
  219.             SENDBYTE ((unsigned char) c);
  220.          }                                       /* switch */
  221.  
  222.       }                                          /* while */
  223.  
  224.    Z_UncorkTransmitter ();                       /* Make sure all is well */
  225. }                                                /* Z_PutString */
  226.  
  227. /*--------------------------------------------------------------------------*/
  228. /* Z SEND HEX HEADER                                                        */
  229. /* Send ZMODEM HEX header hdr of type type                                  */
  230. /*--------------------------------------------------------------------------*/
  231. void Z_SendHexHeader (type, hdr)
  232. unsigned int type;
  233. register unsigned char *hdr;
  234. {
  235.    register int n;
  236.    register int i;
  237.    register word crc;
  238.  
  239.    Z_UncorkTransmitter ();                       /* Get our transmitter going */
  240.  
  241.    SENDBYTE (ZPAD);
  242.    SENDBYTE (ZPAD);
  243.    SENDBYTE (ZDLE);
  244.    SENDBYTE (ZHEX);
  245.    Z_PUTHEX (i, type);
  246.  
  247.    Crc32t = 0;
  248.    crc = Z_UpdateCRC (type, 0);
  249.    for (n = 4; --n >= 0;)
  250.       {
  251.       Z_PUTHEX (i, (*hdr));
  252.       crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
  253.       }
  254.    Z_PUTHEX (i, (crc >> 8));
  255.    Z_PUTHEX (i, crc);
  256.  
  257.    /* Make it printable on remote machine */
  258.    SENDBYTE ('\r');
  259.    SENDBYTE ('\n');
  260.  
  261.    /* Uncork the remote in case a fake XOFF has stopped data flow */
  262.    if (type != ZFIN && type != ZACK)
  263.       SENDBYTE (021);
  264.  
  265.    if (!CARRIER)
  266.       CLEAR_OUTBOUND ();
  267. #ifdef OS_2 /*PLF Sat  05-06-1989  08:32:24 */
  268.     com_wait();
  269. #endif
  270. }                                                /* Z_SendHexHeader */
  271.  
  272. /*--------------------------------------------------------------------------*/
  273. /* Z UNCORK TRANSMITTER                                                     */
  274. /* Wait a reasonable amount of time for transmitter buffer to clear.        */
  275. /*   When it does, or when time runs out, turn XON/XOFF off then on.        */
  276. /*   This should release a transmitter stuck by line errors.                */
  277. /*--------------------------------------------------------------------------*/
  278.  
  279. void Z_UncorkTransmitter ()
  280. {
  281.    long t, timerset ();
  282.  
  283.    if (!OUT_EMPTY ())
  284.       {
  285.       t = timerset (5 * Rxtimeout);              /* Wait for silence */
  286.       while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  287.          time_release ();                        /* Give up slice while
  288.                                                   * waiting  */
  289.       }
  290.    XON_DISABLE ();                               /* Uncork the transmitter */
  291.    XON_ENABLE ();
  292. }
  293.  
  294.  
  295. /*--------------------------------------------------------------------------*/
  296. /* Z GET HEADER                                                             */
  297. /* Read a ZMODEM header to hdr, either binary or hex.                       */
  298. /*   On success, set Zmodem to 1 and return type of header.                 */
  299. /*   Otherwise return negative on error                                     */
  300. /*--------------------------------------------------------------------------*/
  301. int Z_GetHeader (hdr)
  302. byte *hdr;
  303. {
  304.  
  305.    register int c;
  306.    register int n;
  307.    int cancount;
  308.  
  309.    n = cur_baud;                                 /* Max characters before
  310.                                                   * start of frame */
  311.    cancount = 5;
  312.  
  313. Again:
  314.  
  315.    if (got_ESC ())
  316.       {
  317.       send_can ();
  318.       z_log (KBD_msg);
  319.       return ZCAN;
  320.       }
  321.  
  322.    Rxframeind = Rxtype = 0;
  323.  
  324.    switch (c = _Z_TimedRead ())
  325.       {
  326.       case ZPAD:
  327.       case ZPAD | 0200:
  328.          /*-----------------------------------------------*/
  329.          /* This is what we want.                         */
  330.          /*-----------------------------------------------*/
  331.          break;
  332.  
  333.       case RCDO:
  334.       case TIMEOUT:
  335.          goto Done;
  336.  
  337.       case CAN:
  338.  
  339.    GotCan:
  340.  
  341.          if (--cancount <= 0)
  342.             {
  343.             c = ZCAN;
  344.             goto Done;
  345.             }
  346.          switch (c = Z_GetByte (1))
  347.             {
  348.             case TIMEOUT:
  349.                goto Again;
  350.  
  351.             case ZCRCW:
  352.                c = ERROR;
  353.                /* fallthrough... */
  354.  
  355.             case RCDO:
  356.                goto Done;
  357.  
  358.             case CAN:
  359.                if (--cancount <= 0)
  360.                   {
  361.                   c = ZCAN;
  362.                   goto Done;
  363.                   }
  364.                goto Again;
  365.             }
  366.          /* fallthrough... */
  367.  
  368.       default:
  369.  
  370.    Agn2:
  371.  
  372.          if (--n <= 0)
  373.             {
  374.             z_log (FUBAR_msg);
  375.             return ERROR;
  376.             }
  377.  
  378.          if (c != CAN)
  379.             cancount = 5;
  380.          goto Again;
  381.  
  382.       }                                          /* switch */
  383.  
  384.    cancount = 5;
  385.  
  386. Splat:
  387.  
  388.    switch (c = _Z_TimedRead ())
  389.       {
  390.       case ZDLE:
  391.          /*-----------------------------------------------*/
  392.          /* This is what we want.                         */
  393.          /*-----------------------------------------------*/
  394.          break;
  395.  
  396.       case ZPAD:
  397.          goto Splat;
  398.  
  399.       case RCDO:
  400.       case TIMEOUT:
  401.          goto Done;
  402.  
  403.       default:
  404.          goto Agn2;
  405.  
  406.       }                                          /* switch */
  407.  
  408.  
  409.    switch (c = _Z_TimedRead ())
  410.       {
  411.  
  412.       case ZBIN:
  413.          Rxframeind = ZBIN;
  414.          Crc32 = 0;
  415.          c = _Z_GetBinaryHeader (hdr);
  416.          break;
  417.  
  418.       case ZBIN32:
  419.          Crc32 = Rxframeind = ZBIN32;
  420.          c = _Z_32GetBinaryHeader (hdr);
  421.          break;
  422.  
  423.       case ZHEX:
  424.          Rxframeind = ZHEX;
  425.          Crc32 = 0;
  426.          c = _Z_GetHexHeader (hdr);
  427.          break;
  428.  
  429.       case CAN:
  430.          goto GotCan;
  431.  
  432.       case RCDO:
  433.       case TIMEOUT:
  434.          goto Done;
  435.  
  436.       default:
  437.          goto Agn2;
  438.  
  439.       }                                          /* switch */
  440.  
  441.    Rxpos = _Z_PullLongFromHeader (hdr);
  442.  
  443. Done:
  444.  
  445.    return c;
  446. }                                                /* Z_GetHeader */
  447.  
  448. /*--------------------------------------------------------------------------*/
  449. /* Z GET BINARY HEADER                                                      */
  450. /* Receive a binary style header (type and position)                        */
  451. /*--------------------------------------------------------------------------*/
  452. static int _Z_GetBinaryHeader (hdr)
  453. register unsigned char *hdr;
  454. {
  455.    register int c;
  456.    register unsigned int crc;
  457.    register int n;
  458.  
  459.    if ((c = Z_GetZDL ()) & ~0xFF)
  460.       return c;
  461.    Rxtype = c;
  462.    crc = Z_UpdateCRC (c, 0);
  463.  
  464.    for (n = 4; --n >= 0;)
  465.       {
  466.       if ((c = Z_GetZDL ()) & ~0xFF)
  467.          return c;
  468.       crc = Z_UpdateCRC (c, crc);
  469.       *hdr++ = (unsigned char) (c & 0xff);
  470.       }
  471.    if ((c = Z_GetZDL ()) & ~0xFF)
  472.       return c;
  473.  
  474.    crc = Z_UpdateCRC (c, crc);
  475.    if ((c = Z_GetZDL ()) & ~0xFF)
  476.       return c;
  477.  
  478.    crc = Z_UpdateCRC (c, crc);
  479.    if (crc & 0xFFFF)
  480.       {
  481.       z_message (CRC_msg);
  482.       return ERROR;
  483.       }
  484.  
  485.    return Rxtype;
  486. }                                                /* _Z_GetBinaryHeader */
  487.  
  488.  
  489. /*--------------------------------------------------------------------------*/
  490. /* Z GET BINARY HEADER with 32 bit CRC                                      */
  491. /* Receive a binary style header (type and position)                        */
  492. /*--------------------------------------------------------------------------*/
  493. static int _Z_32GetBinaryHeader (hdr)
  494. register unsigned char *hdr;
  495. {
  496.    register int c;
  497.    register unsigned long crc;
  498.    register int n;
  499.  
  500.    if ((c = Z_GetZDL ()) & ~0xFF)
  501.       return c;
  502.    Rxtype = c;
  503.    crc = 0xFFFFFFFF;
  504.    crc = Z_32UpdateCRC (c, crc);
  505.  
  506.    for (n = 4; --n >= 0;)
  507.       {
  508.       if ((c = Z_GetZDL ()) & ~0xFF)
  509.          return c;
  510.       crc = Z_32UpdateCRC (c, crc);
  511.       *hdr++ = (unsigned char) (c & 0xff);
  512.       }
  513.  
  514.    for (n = 4; --n >= 0;)
  515.       {
  516.       if ((c = Z_GetZDL ()) & ~0xFF)
  517.          return c;
  518.  
  519.       crc = Z_32UpdateCRC (c, crc);
  520.       }
  521.  
  522.    if (crc != 0xDEBB20E3)
  523.       {
  524.       z_message (CRC_msg);
  525.       return ERROR;
  526.       }
  527.  
  528.    return Rxtype;
  529. }                                                /* _Z_32GetBinaryHeader */
  530.  
  531. /*--------------------------------------------------------------------------*/
  532. /* Z GET HEX HEADER                                                         */
  533. /* Receive a hex style header (type and position)                           */
  534. /*--------------------------------------------------------------------------*/
  535. static int _Z_GetHexHeader (hdr)
  536. register unsigned char *hdr;
  537. {
  538.    register int c;
  539.    register unsigned int crc;
  540.    register int n;
  541.  
  542.    if ((c = _Z_GetHex ()) < 0)
  543.       return c;
  544.    Rxtype = c;
  545.    crc = Z_UpdateCRC (c, 0);
  546.  
  547.    for (n = 4; --n >= 0;)
  548.       {
  549.       if ((c = _Z_GetHex ()) < 0)
  550.          return c;
  551.       crc = Z_UpdateCRC (c, crc);
  552.       *hdr++ = (unsigned char) c;
  553.       }
  554.  
  555.    if ((c = _Z_GetHex ()) < 0)
  556.       return c;
  557.    crc = Z_UpdateCRC (c, crc);
  558.    if ((c = _Z_GetHex ()) < 0)
  559.       return c;
  560.    crc = Z_UpdateCRC (c, crc);
  561.    if (crc & 0xFFFF)
  562.       {
  563.       z_message (CRC_msg);
  564.       return ERROR;
  565.       }
  566.    if (Z_GetByte (1) == '\r')
  567.       Z_GetByte (1);                             /* Throw away possible cr/lf */
  568.  
  569.    return Rxtype;
  570. }
  571.  
  572. /*--------------------------------------------------------------------------*/
  573. /* Z GET HEX                                                                */
  574. /* Decode two lower case hex digits into an 8 bit byte value                */
  575. /*--------------------------------------------------------------------------*/
  576. static int _Z_GetHex ()
  577. {
  578.    register int c, n;
  579.  
  580.    if ((n = _Z_TimedRead ()) < 0)
  581.       return n;
  582.    n -= '0';
  583.    if (n > 9)
  584.       n -= ('a' - ':');
  585.    if (n & ~0xF)
  586.       return ERROR;
  587.  
  588.    if ((c = _Z_TimedRead ()) < 0)
  589.       return c;
  590.    c -= '0';
  591.    if (c > 9)
  592.       c -= ('a' - ':');
  593.    if (c & ~0xF)
  594.       return ERROR;
  595.  
  596.    return ((n << 4) | c);
  597. }
  598.  
  599. /*--------------------------------------------------------------------------*/
  600. /* Z GET ZDL                                                                */
  601. /* Read a byte, checking for ZMODEM escape encoding                         */
  602. /* including CAN*5 which represents a quick abort                           */
  603. /*--------------------------------------------------------------------------*/
  604. int Z_GetZDL ()
  605. {
  606.    register int c;
  607.  
  608.    if ((c = _Z_qk_read ()) != ZDLE)
  609.       return c;
  610.  
  611.    switch (c = _Z_qk_read ())
  612.       {
  613.       case CAN:
  614.          return ((c = _Z_qk_read ()) < 0) ? c :
  615.             ((c == CAN) && ((c = _Z_qk_read ()) < 0)) ? c :
  616.             ((c == CAN) && ((c = _Z_qk_read ()) < 0)) ? c : (GOTCAN);
  617.  
  618.       case ZCRCE:
  619.       case ZCRCG:
  620.       case ZCRCQ:
  621.       case ZCRCW:
  622.          return (c | GOTOR);
  623.  
  624.       case ZRUB0:
  625.          return 0x7F;
  626.  
  627.       case ZRUB1:
  628.          return 0xFF;
  629.  
  630.       default:
  631.          return (c < 0) ? c :
  632.             ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
  633.  
  634.       }                                          /* switch */
  635. }                                                /* Z_GetZDL */
  636.  
  637. /*--------------------------------------------------------------------------*/
  638. /* Z TIMED READ                                                             */
  639. /* Read a character from the modem line with timeout.                       */
  640. /*  Eat parity, XON and XOFF characters.                                    */
  641. /*--------------------------------------------------------------------------*/
  642. static int _Z_TimedRead ()
  643. {
  644.    register int c;
  645.  
  646.    for (;;)
  647.       {
  648.       if ((c = _Z_qk_read ()) < 0)
  649.          return c;
  650.  
  651.       switch (c &= 0x7F)
  652.          {
  653.          case XON:
  654.          case XOFF:
  655.             continue;
  656.  
  657.          default:
  658.             if (!(c & 0x60))
  659.                continue;
  660.  
  661.          case '\r':
  662.          case '\n':
  663.          case ZDLE:
  664.             return c;
  665.          }                                       /* switch */
  666.  
  667.       }                                          /* for */
  668. }                                                /* _Z_TimedRead */
  669.  
  670. /*--------------------------------------------------------------------------*/
  671. /* Z LONG TO HEADER                                                         */
  672. /* Store long integer pos in Txhdr                                          */
  673. /*--------------------------------------------------------------------------*/
  674. void Z_PutLongIntoHeader (pos)
  675. long pos;
  676. {
  677. #ifndef GENERIC
  678.    /*PLF extern long *TXlong; Fri  05-05-1989  06:45:00 */
  679.  
  680.    /* *TXlong = pos; */
  681.     *((long *) Txhdr) = pos;    /*PLF Fri  05-05-1989  06:45:10 */
  682. #else
  683.    Txhdr[ZP0] = pos;
  684.    Txhdr[ZP1] = pos >> 8;
  685.    Txhdr[ZP2] = pos >> 16;
  686.    Txhdr[ZP3] = pos >> 24;
  687. #endif
  688. }                                                /* Z_PutLongIntoHeader */
  689.  
  690. /*--------------------------------------------------------------------------*/
  691. /* Z PULL LONG FROM HEADER                                                  */
  692. /* Recover a long integer from a header                                     */
  693. /*--------------------------------------------------------------------------*/
  694. static long _Z_PullLongFromHeader (hdr)
  695. unsigned char *hdr;
  696. {
  697. #ifndef GENERIC
  698.    /*PLF extern long *RXlong; somone was sleepy when they did this. */
  699.  
  700.    return (*((long *) Rxhdr)); /*PLF Fri  05-05-1989  06:42:41 */
  701.    hdr;                        /*PLF Fri  05-05-1989  06:42:59 ; Trick to
  702.                                 * keep /W3 happy */
  703. #else
  704.    long l;
  705.  
  706.    l = hdr[ZP3];
  707.    l = (l << 8) | hdr[ZP2];
  708.    l = (l << 8) | hdr[ZP1];
  709.    l = (l << 8) | hdr[ZP0];
  710.    return l;
  711. #endif
  712. }                                                /* _Z_PullLongFromHeader */
  713.  
  714. /* END OF FILE: zmisc.c */
  715.